import {
    PlayGroundWidth,
    PlayGroundHeight,
} from "./canvas.js";
import { GameMap } from "./map.js";
import { TikTok, caculateWidthHeight, tankStore } from "./utils.js";

const BulletSpeed = 5;      // 每个BulletSpeed个tik移动1个block
export class Bullet {
    constructor(opt = {}) {
        const {
            parent,
            power,
            direction,
            coord,
        } = opt;
        this.parent = parent;
        this.power = power;
        this.direction = direction;
        this.coord = {
            x: coord.x,
            y: coord.y,
        };
        this.shape = [[[0, 0], [1, 0], [1, 1], [0, 1]]];
        this.shape[0].opt = {
            fillColor: "#efefef",
        };

        let _fn;
        if (this.direction === "up") {
            _fn = () => { this.coord.y -= 2; };
        } else if (this.direction === "down") {
            _fn = () => { this.coord.y += 2; };
        } else if (this.direction === "left") {
            _fn = () => { this.coord.x -= 2; };
        } else if (this.direction === "right") {
            _fn = () => { this.coord.x += 2; };
        }
        this._refreshStatus = () => {
            if (this.isHitEdge() || this.isHitTankOrBrick() || this.isHitBullet()) {
                // 击中了东西
                this.destroy();
            } else {
                _fn();
            }
        };
        // 每个BulletSpeed个tik刷新一次bullet状态
        TikTok.register(this._refreshStatus, BulletSpeed);
    }

    getType() {
        return "bullet";
    }

    // 是否撞到playground边缘
    isHitEdge() {
        let res = false;
        if (this.direction === "up") {
            res = this.coord.y - 2 < 0;
        } else if (this.direction === "down") {
            res = this.coord.y + 2 > PlayGroundHeight;
        } else if (this.direction === "left") {
            res = this.coord.y - 2 < 0;
        } else if (this.direction === "right") {
            res = this.coord.y + 2 > PlayGroundWidth;
        }
        return res;
    }

    // 是否击中tank或砖头
    isHitTankOrBrick() {
        let x = this.coord.x;
        let y = this.coord.y;
        if (this.direction === "up") {
            y -= 1;
        } else if (this.direction === "down") {
            y += 1;
        } else if (this.direction === "left") {
            x -= 1;
        } else if (this.direction === "right") {
            x += 1;
        }
        // 是否击中tank
        for (let i = 0; i < tankStore.length; i++) {
            let _tank = tankStore[i];
            if (_tank !== this.parent) {
                let { shapeWidth, shapeHeight } = caculateWidthHeight(_tank.attr.shape);
                let xMin = _tank.coord.x;
                let xMax = xMin + shapeWidth;
                let yMin = _tank.coord.y;
                let yMax = yMin + shapeHeight;
                if (x >= xMin && x <= xMax && y >= yMin && y < yMax) {
                    if (_tank.canBeHitByBullet) {
                        _tank.beShot(this);
                        return true;
                    }
                }
            }
        }
        // 是否击中brick
        for (let i = 0; i < GameMap.getCurrentMap()._brickStore.length; i++) {
            let brick = GameMap.getCurrentMap()._brickStore[i];
            let xMin = brick.coord.x;
            let xMax = xMin + brick.shapeWidth;
            let yMin = brick.coord.y;
            let yMax = yMin + brick.shapeHeight;
            if (x >= xMin && x < xMax && y >= yMin && y <= yMax) {
                if (brick.canBeHitByBullet) {
                    brick.beShot(this);
                    return true;
                }
            }
        }
        return false;
    }

    // 是否集中其他bullet
    isHitBullet() {
        let _arrBullets = tankStore.reduce((acc, _tank) => {
            acc.push(..._tank._bulletStore);
            return acc;
        }, []);
        let res = false;
        for (let i = 0; i < _arrBullets.length; i++) {
            let _bullet = _arrBullets[i];
            if (_bullet !== this) {
                if (Math.abs(this.coord.x - _bullet.coord.x) < 2 && Math.abs(this.coord.y - _bullet.coord.y) < 2) {
                    res = true;
                    _bullet.destroy(this);
                    break;
                }
            }
        }
        return res;
    }

    destroy() {
        TikTok.unRegister(this._refreshStatus);
        this.parent.removeBullet(this);
    }
}
